package j2EE.handler;

import j2EE.dispatcher.Dispatcher;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * Created with Intel IDEA.
 * 前端控制器 : 从逻辑上说他应该是一个框架。 而不仅仅是容器。
 *  直接工作就是管理调度器，利用他们选择视图，一旦视图选择好，前端控制器就把控制权移交给视图
 *
 *  使用的服务工作模式，控制器已经被划分成一组可重用的组件： 一个前端控制器，一些调度器和动作.
 *      前端控制器： 管理调度器，利用他们选择视图
 *      调度器：选择产生的视图
 *      动作：更新模型视图
 *  注意；添加新页面是动态的，产生的jsp 视图和对应的动作类，添加到xml 中。需要添加，删除，重新排序的时候只需要修改xml 文件。
 * @Auther: gjt
 * @Date: 2024/9/8 11:03
 */
public class FrontController extends HttpServlet {
    private static final String DISPATCHER_ATTR = "Dispatcher";
    private static final String DISPATCHER_PREFIX = "j2ee.dispatcher.";

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

    // 进程得到请求
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        process(req, resp);
    }

    // 进程发送请求
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        process(req, resp);
    }

    // 常用处理例程
    public void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        ServletContext context = getServletContext();

        // 在较低情况中获取请求的末尾元素
        String reqPath = request.getPathInfo();
        reqPath = Character.toUpperCase(reqPath.charAt(1)) + reqPath.substring(2).toLowerCase();// 第一个字符大写，其他小写

        // 在会话中查找调度器
        Dispatcher dispatcher = (Dispatcher) session.getAttribute(reqPath + DISPATCHER_ATTR);

        // 如果没有找到，就创建一个
        if (dispatcher == null) {
            String className = reqPath + "Dispatcher";
            try {
                Class c = Class.forName(DISPATCHER_PREFIX + className);
                dispatcher = (Dispatcher) c.newInstance();
            } catch (Exception e) {
                throw new ServletException("Can't find class" + className, e);
            }

            // 再会话中保存调度器
            dispatcher.setContext(context);
            session.setAttribute(reqPath + DISPATCHER_ATTR, dispatcher);
        }

        // 使用调度器查找页
        String nextPage = dispatcher.getNextPage(request, context);

        // 确保我们没有缓存动态数据
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");

        // 将控制器转发 到 视图
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/" + nextPage);
        requestDispatcher.forward(request, response);
    }
}
